package com.cx.mall.demo.utils;

import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.cx.mall.demo.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * 验证码服务类，负责生成、发送和验证验证码
 */
@Service
public class VerificationCodeService {

    private static final Logger log = LoggerFactory.getLogger(VerificationCodeService.class);
    @Autowired
    private SmsUtils smsUtils;
    @Autowired
    private UserService userService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    // 验证码长度
    private static final int CODE_LENGTH = 6;
    // 验证码有效期(分钟)
    private static final int CODE_EXPIRE_MINUTES = 5;
    // 同一手机号发送间隔(秒)
    private static final int SEND_INTERVAL_SECONDS = 60;

    /**
     * 生成随机验证码
     */
    private String generateCode() {
        Random random = new Random();
        StringBuilder code = new StringBuilder();
        for (int i = 0; i < CODE_LENGTH; i++) {
            code.append(random.nextInt(10));
        }
        return code.toString();
    }

    /**
     * 发送验证码到指定手机号
     */
    public boolean sendCode(String phoneNumber) {
        //检查手机号格式
        if (!isValidPhoneNumber(phoneNumber)) {
            System.out.println("手机号格式不正确: " + phoneNumber);
            return false;
        }

        //检查手机号是否已注册
        if (!userService.isPhoneRegistered(phoneNumber)) {
            System.out.println("手机号未注册: " + phoneNumber);
            return false;
        }

        // 检查发送频率
        String intervalKey = "sms:interval:" + phoneNumber;
        if (redisTemplate.hasKey(intervalKey)) {
            System.out.println("发送频率过高，请稍后再试: " + phoneNumber);
            return false;
        }

        try {
            // 生成验证码
            String code = generateCode();

            // 发送短信
            SendSmsResponse response = smsUtils.sendSms(phoneNumber, code);

            // 发送成功则保存验证码到Redis
            if ("OK".equals(response.getCode())) {
                // 存储验证码，设置过期时间
                String codeKey = "sms:code:" + phoneNumber;
                redisTemplate.opsForValue().set(codeKey, code, CODE_EXPIRE_MINUTES, TimeUnit.MINUTES);

                // 设置发送间隔限制
                redisTemplate.opsForValue().set(intervalKey, "1", SEND_INTERVAL_SECONDS, TimeUnit.SECONDS);

                System.out.println("验证码发送成功: " + phoneNumber + ", 验证码: " + code);
                return true;
            } else {
                System.out.println("验证码发送失败: " + response.getMessage() + ", 错误码: " + response.getCode());
                return false;
            }
        } catch (ClientException e) {
            log.error(e.getMessage());
//            System.out.println("发送验证码异常: " + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 验证验证码是否正确
     */
    public boolean verifyCode(String phoneNumber, String code) {
        if (!isValidPhoneNumber(phoneNumber) || code == null || code.length() != CODE_LENGTH) {
            return false;
        }

        String codeKey = "sms:code:" + phoneNumber;
        String storedCode = redisTemplate.opsForValue().get(codeKey);

        // 验证成功后删除验证码，防止重复使用
        if (code.equals(storedCode)) {
            redisTemplate.delete(codeKey);
            return true;
        }

        return false;
    }

    /**
     * 验证手机号格式
     */
    private boolean isValidPhoneNumber(String phoneNumber) {
        return phoneNumber != null && phoneNumber.matches("^1[3-9]\\d{9}$");
    }
}
